﻿using Caliburn.Micro;
using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SD.IOC.Core.Mediators;
using SlamDunk.MES.IAppService.DTOs.Inputs;
using SlamDunk.MES.IAppService.DTOs.Outputs.ResourceContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.MES.Presentation.Models.NotifyModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Threading.Tasks;
using System.Windows;

namespace SlamDunk.MES.Client.ViewModels.SaleOrder
{
    /// <summary>
    /// 销售订单创建视图模型
    /// </summary>
    public class AddViewModel : ScreenBase
    {
        #region # 字段及构造器

        /// <summary>
        /// 编号生成服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<INumberContract> _numberContract;

        /// <summary>
        /// 计划管理服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IPlanContract> _planContract;

        /// <summary>
        /// 窗口管理器
        /// </summary>
        private readonly IWindowManager _windowManager;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public AddViewModel(ServiceProxy<INumberContract> numberContract, ServiceProxy<IPlanContract> planContract, IWindowManager windowManager)
        {
            this._numberContract = numberContract;
            this._planContract = planContract;
            this._windowManager = windowManager;
        }

        #endregion

        #region # 属性

        #region 销售订单编号 —— string SaleOrderNo
        /// <summary>
        /// 销售订单编号
        /// </summary>
        [DependencyProperty]
        public string SaleOrderNo { get; set; }
        #endregion

        #region 销售订单名称 —— string SaleOrderName
        /// <summary>
        /// 销售订单名称
        /// </summary>
        [DependencyProperty]
        public string SaleOrderName { get; set; }
        #endregion

        #region 已选客户 —— EnterpriseInfo SelectedCustomer
        /// <summary>
        /// 已选客户
        /// </summary>
        [DependencyProperty]
        public EnterpriseInfo SelectedCustomer { get; set; }
        #endregion

        #region 下单日期 —— DateTime? IssuedDate
        /// <summary>
        /// 下单日期
        /// </summary>
        [DependencyProperty]
        public DateTime? IssuedDate { get; set; }
        #endregion

        #region 交付日期 —— DateTime? DeliveryDate
        /// <summary>
        /// 交付日期
        /// </summary>
        [DependencyProperty]
        public DateTime? DeliveryDate { get; set; }
        #endregion

        #region 描述 —— string Description
        /// <summary>
        /// 描述
        /// </summary>
        [DependencyProperty]
        public string Description { get; set; }
        #endregion

        #region 客户列表 —— ObservableCollection<EnterpriseInfo> Customers
        /// <summary>
        /// 客户列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<EnterpriseInfo> Customers { get; set; }
        #endregion

        #region 销售订单明细列表 —— ObservableCollection<SaleOrderDetail> Details
        /// <summary>
        /// 销售订单明细列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<SaleOrderDetailNm> Details { get; set; }
        #endregion

        #endregion

        #region # 方法

        //Initializations

        #region 加载 —— async Task Load(IEnumerable<EnterpriseInfo> customers)
        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="customers">客户列表</param>
        public async Task Load(IEnumerable<EnterpriseInfo> customers)
        {
            this.Customers = new ObservableCollection<EnterpriseInfo>(customers);
            this.SaleOrderNo = await Task.Run(() => this._numberContract.Channel.GenerateSaleOrderNo());
            this.Details = new ObservableCollection<SaleOrderDetailNm>();
        }
        #endregion


        //Actions

        #region 创建销售订单明细 —— async void CreateDetail()
        /// <summary>
        /// 创建销售订单明细
        /// </summary>
        public async void CreateDetail()
        {
            AddDetailViewModel viewModel = ResolveMediator.Resolve<AddDetailViewModel>();

            this.Busy();
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            this.Idle();

            if (result == true)
            {
                SaleOrderDetailNm detailNm = this.Details.SingleOrDefault(x => x.ProductId == viewModel.SelectedProduct.Id && x.ProductionBatchNo == viewModel.ProductionBatchNo);
                if (detailNm == null)
                {
                    detailNm = new SaleOrderDetailNm
                    {
                        ProductId = viewModel.SelectedProduct.Id,
                        ProductNo = viewModel.SelectedProduct.Number,
                        ProductName = viewModel.SelectedProduct.Name,
                        Quantity = viewModel.Quantity ?? 0,
                        Unit = viewModel.Unit,
                        ProductionBatchNo = viewModel.ProductionBatchNo,
                        Description = viewModel.Description
                    };
                    this.Details.Add(detailNm);
                }
                else
                {
                    detailNm.Quantity += viewModel.Quantity ?? 0;
                }
            }
        }
        #endregion

        #region 删除销售订单明细 —— void RemoveDetail(SaleOrderDetail detail)
        /// <summary>
        /// 删除销售订单明细
        /// </summary>
        /// <param name="detailNm">销售订单明细</param>
        public void RemoveDetail(SaleOrderDetailNm detailNm)
        {
            this.Details.Remove(detailNm);
        }
        #endregion

        #region 提交 —— async void Submit()
        /// <summary>
        /// 提交
        /// </summary>
        public async void Submit()
        {
            #region # 验证

            if (string.IsNullOrWhiteSpace(this.SaleOrderNo))
            {
                MessageBox.Show("销售订单编号不可为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (string.IsNullOrWhiteSpace(this.SaleOrderName))
            {
                MessageBox.Show("销售订单名称不可为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (this.SelectedCustomer == null)
            {
                MessageBox.Show("客户不可为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (this.IssuedDate == null)
            {
                MessageBox.Show("下单日期不可为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (this.DeliveryDate == null)
            {
                MessageBox.Show("交付日期不可为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (!this.Details.Any())
            {
                MessageBox.Show("销售订单明细不可为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            #endregion

            this.Busy();

            string orderNo = this.SaleOrderNo;
            string orderName = this.SaleOrderName;
            Guid customerId = this.SelectedCustomer.Id;
            DateTime issuredDate = this.IssuedDate.Value.Date;
            DateTime deliveryDate = this.DeliveryDate.Value.Date;
            string description = this.Description;
            IEnumerable<SaleOrderDetailParam> detailParams =
                from detail in this.Details
                select new SaleOrderDetailParam
                {
                    productId = detail.ProductId,
                    quantity = detail.Quantity,
                    productionBatchNo = detail.ProductionBatchNo,
                    sort = this.Details.IndexOf(detail),
                    description = detail.Description
                };

            await Task.Run(() => this._planContract.Channel.CreateSaleOrder(orderNo, orderName, customerId, issuredDate, deliveryDate, description, detailParams));

            await base.TryCloseAsync(true);
            this.Idle();
        }
        #endregion

        #endregion
    }
}
